﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufImpl.h"
#include "GnufComponentDeclaration.h"
#include "GnufSubject.h"
#include "GnufBaseUtils.h"

#define GNUF_SPLASH_SCREEN_PROC  L"GNUF_SPLASH_SCREEN_PROC"

namespace gnuf {
    class SplashScreen;
    class WelcomePanel;
    class Desktop;
    class WindowTitleBar;
    class DeveloperToolbar;
    class QtWorkBenchWindow;
    class WelcomePanelEx;
    class WelcomePanelWorkStage;
    class DesktopWorkStage;
    class SdkImplement;
    class Preferences;
    class ColorPalette;
    class StyleSheetComposer;
    class HotKeyInputBox;
    class ApplicationVersionDlg;
    class ResourceConfiguration;
    class ButtonControlTracker;
    class ScenarioManager;
    class AsynchronousTaskManager;
    class Scenario;
    class MainTitleBar;
    class WorkspaceTabBar;
    class PreferencesPallet;
    class DynamicZone;
    class AssistantPanel;
    class HotkeyManager2;
    class ModuleManager;
    class ModuleBar;
    class WorkBench;
    class AnnouncementManager;
    class Usurper;

    namespace impl {
        class WorkBenchImpl final
        {
            GNUF_IMPL_USED_BY(WorkBench);
        public:
            GNUF_IMPL_CLASS(WorkBench)();
            ~GNUF_IMPL_CLASS(WorkBench)();
            void initialize();
            void setWantToParentIsolatedWindow(bool val) { m_wantToParentIsolatedWindow = val; }
            bool wantToParentIsolatedWindow() const { return m_wantToParentIsolatedWindow; }
        private:
            EWorkStage m_workStage;
            std::wstring m_windowIconFilename;
            std::wstring m_defaultWindowTitle;
            bool m_developerToolbarEnabled;
            gcmp::OwnerPtr< Usurper >           m_opUsurper;
            gcmp::OwnerPtr< QtWorkBenchWindow > m_qtWorkBenchWindow;
            gcmp::OwnerPtr< SplashScreen >      m_splashScreen;
            gcmp::OwnerPtr< WelcomePanel >      m_welcomePanel;
            gcmp::OwnerPtr< WelcomePanelEx >    m_welcomePanelEx;

            gcmp::OwnerPtr< WelcomePanelWorkStage > m_welcomePanelWorkStage;
            gcmp::OwnerPtr< DesktopWorkStage > m_desktopWorkStage;
            std::list< gcmp::OwnerPtr< SdkImplement > > m_listSdkImplement;

            gcmp::OwnerPtr< AnnouncementManager > m_opAnnMgr;

            gcmp::OwnerPtr< Preferences > m_preferences, m_minorPreferences;
            gcmp::OwnerPtr< PreferencesPallet > m_opPreferencePallet;
            gcmp::OwnerPtr< ColorPalette > m_colorPalette;
            gcmp::OwnerPtr< StyleSheetComposer > m_styleSheetComposer;
            gcmp::OwnerPtr< HotKeyInputBox > m_hotkeyInputBox;
            Color m_backgroundColor;
            gcmp::OwnerPtr< ApplicationVersionDlg > m_applicationDlg;

            gcmp::OwnerPtr< ResourceConfiguration > m_resConfig;
            gcmp::OwnerPtr< ButtonControlTracker > m_buttonControlTracker;
            gcmp::OwnerPtr< ScenarioManager > m_scenarioManager;
            gcmp::OwnerPtr< AsynchronousTaskManager > m_asynchronousTaskManager;

            gcmp::OwnerPtr< HotkeyManager2 > m_opHotkeyMgr;
            gcmp::OwnerPtr< ModuleManager > m_opModuleMgr;
            gcmp::OwnerPtr< ModuleBar > m_opModuleBar;
            gcmp::OwnerPtr< DynamicZone > m_dynamicZone;
            gcmp::OwnerPtr< AssistantPanel > m_assistantPanel;

            bool m_wantToParentIsolatedWindow = false;
        };
    }
}

namespace gnuf {

    class WorkBenchObserver
    {
    public:
        virtual ~WorkBenchObserver() {}
        virtual void initializeSDKImplement(std::list<gcmp::OwnerPtr<SdkImplement>>&) {};
    };

    class GNUF_BASE_EXPORT WorkBench final : public Subject<WorkBenchObserver>
    {
        GNUF_IMPL_USE(WorkBench);
    public:
        static WorkBench * get();
    
        WorkBench();
        virtual ~WorkBench();

    public:
        void initialize();

        const QtWorkBenchWindow * qtWorkBenchWindow() const {
            return impl()->m_qtWorkBenchWindow.get();
        }
        QtWorkBenchWindow * qtWorkBenchWindow() {
            return impl()->m_qtWorkBenchWindow.get();
        }

        std::uint64_t windowId() const;
        Desktop* desktop();
        
        void setWorkStage(const EWorkStage);
        EWorkStage workStage() const { return impl()->m_workStage; }
        
        // By default, the developer toolbar is disabled. The client
        // has to invoke this method to enable explicitly it.
        void enableDeveloperToolbar() { impl()->m_developerToolbarEnabled = true; }
        bool developerToolbarEnabled() const { return impl()->m_developerToolbarEnabled; }

        DeveloperToolbar * developerToolbar();
        DeveloperToolbar * welcomePanelDeveloperToolbar();
        WindowTitleBar * windowTitleBar();

        /// \brief 获取mainTitleBar
        MainTitleBar* mainTitleBar();

        /// \brief 获取标签栏
        WorkspaceTabBar* workspaceTabBar();

        WelcomePanel * welcomePanel() { return impl()->m_welcomePanel.get(); }
        WelcomePanelEx* welcomePanelEx() { return impl()->m_welcomePanelEx.get(); }

        const Preferences * preferences() const { return impl()->m_preferences.get(); }
              Preferences * preferences()       { return impl()->m_preferences.get(); }
        /// \brief Show the old dialog for the preferences.
        void showPreferenceSettingDialog();
        /// \brief Show the new pallet for the preferences
        void showPreferencePallet();

        Preferences * minorPreferences() { return impl()->m_minorPreferences.get(); }

        const ColorPalette * colorPalette() const { return impl()->m_colorPalette.get(); }
        const StyleSheetComposer * styleSheetComposer() const { return impl()->m_styleSheetComposer.get(); }
        StyleSheetComposer * styleSheetComposer();

        void setBackgroundColor(const Color& color) { impl()->m_backgroundColor = color; }
        const Color& backgroundColor() const { return impl()->m_backgroundColor; }

        void setWindowIcon(const std::wstring & dir, const std::wstring & fileName);
        std::wstring windowIcon() const;

        void setDefaultWindowTitle(const std::wstring & title) { 
            impl()->m_defaultWindowTitle = title;
        }
        const std::wstring & defaultWindowTitle() const {
            return impl()->m_defaultWindowTitle;
        }

		void setApplicationName(const std::wstring& displayName);

        void showMinimized();
        bool isManimized() const;
        void showMaximized();
        bool isMaximized() const;
        void showNormal();
        void activateWindow();
        void move(int, int);
        void offset(int deltaX, int deltaY);

        void respondTo(const Preferences *);
        void respondTo(const Scenario *, bool started);

        ///\brief Set whether want to parent the isolated window. By default, don't want.
        ///\note If the main window parents an isolated window, the isolated window is always on
        /// the top of the main window, but doesn't have an entry on Window Taskbar. If the main
        /// window doesn't parent an isolated window, the isolated window has an entry on Window
        /// Taskbar, and is on the top of the main window only when activated.
        void setWantToParentIsolatedWindow(bool);
        ///\return Return true if want. Otherwise, return false. By default, return false.
        bool wantToParentIsolatedWindow() const;
    };
}
